library ieee;
use ieee.std_logic_1164.all;

entity selectBlock is
	port (
		Din : in bit_vector(31 downto 0);
		S : in bit_vector(1 downto 0);
		Dout : out bit_vector(31 downto 0);
		Carry : out bit
	);
end entity selectBlock;

architecture STRUCTURAL of selectBlock is

	component mux2to1
		port (
			I0, I1, S : in bit;
        	F : out bit
        );
	end component;
	
	component and2
		port (
			a,b : in bit;
			z : out bit
		);
	end component;
	
	component not1
		port (
			a : in bit;
			z : out bit
		);
	end component;
	
	component or2
		port (
			a,b : in bit;
			z : out bit
		);
	end component;
	
	for all : mux2to1 use entity work.mux2to1(DATAFLOW);
	for all : and2 use entity work.and2(DATAFLOW);
	for all : or2 use entity work.or2(DATAFLOW);
	for all : not1 use entity work.notDataFlow(DATAFLOW);
	
	signal S_not : bit_vector(1 downto 0);
	signal and_out : bit_vector(2 downto 0);
	signal and_not : bit;
	signal mux_out : bit_vector(31 downto 0);
	signal data_not : bit_vector(31 downto 0);
	signal or_out : bit;
	signal or_not : bit;
	signal carry_select : bit;
	
begin

	not_0 : not1 port map(S(1), S_not(1));
	not_1 : not1 port map(S(0), S_not(0));
	not_2 : not1 port map(and_out(0), and_not);
	not_3 : not1 port map(or_out, or_not);
	
	not_data0 : not1 port map(Din(0), data_not(0));
	not_data1 : not1 port map(Din(1), data_not(1));
	not_data2 : not1 port map(Din(2), data_not(2));
	not_data3 : not1 port map(Din(3), data_not(3));
	not_data4 : not1 port map(Din(4), data_not(4));
	not_data5 : not1 port map(Din(5), data_not(5));
	not_data6 : not1 port map(Din(6), data_not(6));
	not_data7 : not1 port map(Din(7), data_not(7));
	not_data8 : not1 port map(Din(8), data_not(8));
	not_data9 : not1 port map(Din(9), data_not(9));
	not_data10 : not1 port map(Din(10), data_not(10));
	not_data11 : not1 port map(Din(11), data_not(11));
	not_data12 : not1 port map(Din(12), data_not(12));
	not_data13 : not1 port map(Din(13), data_not(13));
	not_data14 : not1 port map(Din(14), data_not(14));
	not_data15 : not1 port map(Din(15), data_not(15));
	not_data16 : not1 port map(Din(16), data_not(16));
	not_data17 : not1 port map(Din(17), data_not(17));
	not_data18 : not1 port map(Din(18), data_not(18));
	not_data19 : not1 port map(Din(19), data_not(19));
	not_data20 : not1 port map(Din(20), data_not(20));
	not_data21 : not1 port map(Din(21), data_not(21));
	not_data22 : not1 port map(Din(22), data_not(22));
	not_data23 : not1 port map(Din(23), data_not(23));
	not_data24 : not1 port map(Din(24), data_not(24));
	not_data25 : not1 port map(Din(25), data_not(25));
	not_data26 : not1 port map(Din(26), data_not(26));
	not_data27 : not1 port map(Din(27), data_not(27));
	not_data28 : not1 port map(Din(28), data_not(28));
	not_data29 : not1 port map(Din(29), data_not(29));
	not_data30 : not1 port map(Din(30), data_not(30));
	not_data31 : not1 port map(Din(31), data_not(31));
	
	and_out(0) <= S_not(1) and S(0);
	and_out(1) <= S(1) and S(0);
	and_out(2) <= S_not(1) and S_not(0);
	carry_select <= or_not and and_not;
	
	or_out <= and_out(1) or and_out(2);
	
	carry_mux : mux2to1 port map('0', '1', carry_select, Carry);

	generate_sequence : for i in 0 to 31 GENERATE
		mux_0 : mux2to1 port map(data_not(i), Din(i), and_out(0), mux_out(i));
		mux_1 : mux2to1 port map(mux_out(i), '0', or_out, Dout(i));
	END GENERATE ;
	
end architecture STRUCTURAL;